/*
 * @Description:字典类
 * @Autor: wangxin
 * @Date: 2020-06-13 09:29:24
 * @LastEditTime: 2020-06-13 14:09:38
 */
/**
 * 将key转化为字符串
 */
function defauiltToString(item) {
  if (item === null) {
    return 'NULL'
  } else if (item === undefined) {
    return 'UNDEFINED'
  } else if (typeof item === 'string' || item instanceof String) {
    return `${item}`
  }
  return item.toString()
}

/**
 * 键值类对象
 */
class ValuePair {
  constructor(key, value) {
    this.key = key
    this.value = value
  }
  toString() {
    return `[${this.key}:${this.value}]`
  }
}

/**
 * 创建字典类
 */
class Dictionary {
  constructor(toStrFn = defauiltToString) {
    this.toStrFn = toStrFn
    this.table = {}
  }

  /**
   * 检测一个键是否存在于字典中
   */
  haskey(key) {
    return this.table[this.toStrFn(key)] !== null
  }

  /**
   * 向字典中添加元素,如果存在，会覆盖
   */
  set(key, value) {
    if (key !== null && value !== null) {
      const tableKey = this.toStrFn(key)
      this.table[tableKey] = new ValuePair(key, value)
      return true
    }
    return false
  }

  /**
   * 从字典中移除一个元素
   */
  remove(key) {
    if (this.haskey(key)) {
      delete this.table[this.toStrFn(key)]
      return true
    }
    return false
  }

  /**
   * 从字典中检索一个值
   */
  get(key) {
    if (this.haskey(key)) {
      return this.table[this.toStrFn(key)].value
    }
    return undefined
  }

  /**
   * 以数组形式返回键值对象
   */
  keyValues() {
    // return Object.values(this.table)
    const valuePairs = []
    for (const k in this.table) {
      if (this.haskey(k)) {
        valuePairs.push(this.table[k])
      }
    }
    return valuePairs
  }

  /**
   * 返回键名
   */
  keys() {
    // return this.keyValues().map((valuePairs) => valuePairs.key)
    const keys = []
    const valuePairs = this.keyValues()
    for (let i = 0; i < valuePairs.length; i++) {
      keys.push(valuePairs[i].key)
    }
    return keys
  }

  /**
   * 返回值
   */
  values() {
    return this.keyValues().map((valuePairs) => valuePairs.value)
  }

  /**
   * 用forEach迭代字典中的每个键值对
   */
  forEach(callbackFn) {
    const valuePairs = this.keyValues()
    for (let i = 0; i < valuePairs.length; i++) {
      const result = callbackFn(valuePairs[i].key, valuePairs[i].value)
      if (result === false) {
        break
      }
    }
  }

  clear() {
    this.table = {}
  }

  isEmpty() {
    return this.size() === 0
  }

  size() {
    return Object.keys(this.table).length
  }

  toString() {
    if (this.isEmpty()) {
      return ''
    }
    const valuePairs = this.keyValues()
    let objString = `${valuePairs[0].toString()}`
    for (let i = 1; i < valuePairs.length; i++) {
      objString = `${objString},${valuePairs[i].toString()}`
    }
    return objString
  }
}

// 代码测试
// const dic = new Dictionary()
// dic.set('张三', '12332378453285')
// dic.set('李四', '1212121212121313')
// dic.set('王麻子', '212121212121313')
// dic.forEach((key, value) => {
//   console.log(key, value)
// })
// console.log(dic.get('张三'))
